﻿using System;
using System.ComponentModel;
using System.Net.Sockets;
using System.Net;
using System.Text;
using SuperX.DataService.Abstract;
using SuperX.DataService;
using SuperX.Common.Abstract;
using SuperX.Common;
using HslCommunication.Core.Net;
using HslCommunication.Serial;
using SuperX.Common.Log;
using System.Collections.Generic;
using HslCommunication.Core;
using HslCommunication.ModBus;
using HslCommunication.Profinet.Melsec;

namespace SuperX.ModbusDriver
{
    [Description("Modbus TCP协议")]
    public class ModbusTCPReader : ModbusBase                    //IPLCDriver : IDriver, IReaderWriter       IDriver : IDisposable
    {
        private ModbusTcpNet client = new ModbusTcpNet();
        public override IByteTransform ByteTransform { get => client.ByteTransform; }

        public override IReadWriteNet ReadWriteNet => client;

        public override int PDU => 10;

        public ModbusTCPReader() : base()
        {
        }

        public override bool IsClosed
        {
            get
            {
                //if (tcpSynCl == null) Logger.Warn($"{Name}断开连接！");
                return PlcReadWrite == null || !_connected;
            }
        }

        public ModbusTCPReader(IDataServer server, string name, string nodeName) : base(server, name, nodeName)
        {
        }

        public override bool Connect()
        {
            if (string.IsNullOrEmpty(_ip)) return false;
            if (PlcReadWrite != null)
            {
                try
                {
                    client.ConnectClose();
                    client.Dispose();
                }
                catch (Exception err)
                {
                    Logger.Exception(err);
                }
            }
            client = new ModbusTcpNet();
            client.IpAddress = _ip;
            client.Port = Port;
            client.DataFormat = DataFormat;
            client.ReceiveTimeOut = _timeout;
            client.Station = SalveId;
            PlcReadWrite = client;
            var result = client.ConnectServer();
            return _connected = result.IsSuccess;
        }

        public override void Dispose()
        {
            client?.ConnectClose();
            client?.Dispose();
            client = null;
            base.Dispose();
        }

        public override Dictionary<string, string> GetRegester()
        {
            return new Dictionary<string, string>()
            {
                { "x=1;","x=1;"},{ "x=2;","x=2;"},{ "x=3;","x=3;"},{ "x=4;","x=4;"}
            };
        }

        public override DeviceAddress GetDeviceAddress(TagConfig meta)
        {
            var address = meta.Address;
            DeviceAddress dv = DeviceAddress.Empty;
            dv.Addr = address;
            dv.VarType = meta.DataType;
            try
            {
                if (string.IsNullOrEmpty(meta.Regester) || string.IsNullOrEmpty(meta.No))
                    return dv;
                address = meta.No;
                switch (meta.Regester)
                {
                    case "x=1;":
                        {
                            dv.DBNumber = Modbus.fctReadCoil;
                            int st;
                            int.TryParse(address, out st);
                            dv.Start = st;
                            dv.GatherType = GatherType.Digital;
                        }
                        break;

                    case "x=2;":
                        {
                            dv.DBNumber = Modbus.fctReadDiscreteInputs;
                            int st;
                            int.TryParse(address, out st);
                            dv.Start = st;
                            dv.GatherType = GatherType.Digital;
                        }
                        break;

                    case "x=4;":
                        {
                            int index = address.IndexOf('.');
                            dv.DBNumber = Modbus.fctReadHoldingRegister;
                            if (index > 0)
                            {
                                dv.Start = int.Parse(address.Substring(index - 1));
                                dv.Bit = byte.Parse(address.Substring(index + 1));
                                dv.GatherType = GatherType.Digital;
                            }
                            else
                            {
                                dv.Start = int.Parse(address);
                                dv.GatherType = GatherType.Analogue;
                            }
                            dv.ByteOrder = ByteOrder.Network;
                        }
                        break;

                    case "x=3;":
                        {
                            int index = address.IndexOf('.');
                            dv.DBNumber = Modbus.fctReadInputRegister;
                            if (index > 0)
                            {
                                dv.Start = int.Parse(address.Substring(index - 1));
                                dv.Bit = byte.Parse(address.Substring(index + 1));
                            }
                            else
                            {
                                dv.Start = int.Parse(address);
                                dv.GatherType = GatherType.Analogue;
                            }
                            dv.ByteOrder = ByteOrder.Network;
                        }

                        break;
                }
            }
            catch (Exception)
            {
                Logger.Warn($"{address}地址格式有误！");
            }
            return dv;
        }
    }
}